package com.uzai.console.service.module.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.uzai.common.enums.*;
import com.uzai.common.exception.BusinessException;
import com.uzai.common.result.ResponseCode;
import com.uzai.common.utils.Math;
import com.uzai.console.common.utils.DateUtil;
import com.uzai.console.common.utils.Tools;
import com.uzai.console.config.UzaiConsoleSysConfig;
import com.uzai.console.dto.alipaydetail.AlipayDetailCreateDto;
import com.uzai.console.dto.device.deviceauth.DeviceAuthQuery;
import com.uzai.console.dto.module.deviceproduct.DeviceProductQuery;
import com.uzai.console.dto.module.product.MerchantSetProductDto;
import com.uzai.console.dto.module.product.ProductBuyAuthDto;
import com.uzai.console.dto.module.product.ProductQuery;
import com.uzai.console.dto.wechatprivate.devicewechatinfo.DeviceWechatInfoQuery;
import com.uzai.console.dto.wechatwork.devicewxworkinfo.DeviceWxworkInfoQuery;
import com.uzai.console.dto.wxpubmanage.WxpubInfoListQuery;
import com.uzai.console.entity.*;
import com.uzai.console.enums.AlipayStatusEnum;
import com.uzai.console.enums.AlipayTypeEnum;
import com.uzai.console.enums.MerAccDetailSourceTypeEnum;
import com.uzai.console.mapper.*;
import com.uzai.console.service.alipaydetail.AlipayDetailService;
import com.uzai.console.service.module.ProductAuthService;
import com.uzai.console.vo.alipaydetail.businessinfo.ProductAuthBusinessInfo;
import com.uzai.console.vo.module.product.BuyProductAuthVo;
import com.uzai.console.vo.module.product.ProductAuthVo;
import io.swagger.models.auth.In;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/***
 * 运营商基本配置
 * @author liuqi
 * @date 2021年08月13日 11:34
 */
@Service
public class ProductAuthServiceImpl implements ProductAuthService {

    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private DeviceProductMapper deviceProductMapper;
    @Autowired
    private ProductAuthMapper productAuthMapper;
    @Autowired
    private ProductPriceMapper productPriceMapper;
    @Autowired
    private MerBaseConfigMapper merBaseConfigMapper;
    @Autowired
    private AlipayDetailService alipayDetailService;
    @Autowired
    private AlipayDetailMapper alipayDetailMapper;
    @Autowired
    private MerchantMapper merchantMapper;
    @Autowired
    private MerAccDetailMapper merAccDetailMapper;
    @Autowired
    private ProductAuthDetailMapper productAuthDetailMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UzaiConsoleSysConfig uzaiConsoleSysConfig;
    @Autowired
    private DeviceWechatInfoMapper deviceWechatInfoMapper;
    @Autowired
    private DeviceWxworkInfoMapper deviceWxworkInfoMapper;
    @Autowired
    private WxpubInfoMapper wxpubInfoMapper;

    /**
     * 查询运营商产品列表
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param merId
     * @return null
     */
    public List<ProductAuthVo> findProAuthList(Long merId){

        //取当前时间
        Integer now = DateUtil.getNowTime();

        //返回产品列表
        List<ProductAuthVo> productAuthVoList =  new ArrayList<>();

        //查询当前有效的产品
        ProductQuery productQuery = new ProductQuery();
        productQuery.setStatus(1); //1-有效；0-禁用
        ArrayList<Product> productList =  productMapper.findByList(productQuery);
        //循环遍历产品功能，如果该运营商启用了该产品功能，就设置status=1,否则status=0
        if(productList != null && productList.size() > 0){

            //查询当前运营商的设备类型配置
            MerBaseConfig merBaseConfig = merBaseConfigMapper.selectByMerId(merId, MerConfigKeyEnum.PRODUCT_SWITCH.getValue());

            for (Product product : productList){
                ProductAuthVo productAuthVo = new ProductAuthVo();
                //对象互相赋值属性
                BeanUtils.copyProperties(product, productAuthVo);
                //功能产品
                productAuthVo.setProductType(0);

                //查询当前运营商的产品功能配置
                ProductAuth productAuth = productAuthMapper.selectByMerIdAndProductCode(merId, product.getCode());
                if(productAuth != null ){
                    productAuthVo.setProductAuthStatus(1); //有授权
                    productAuthVo.setExpireTime(productAuth.getExpireTime());
                    if(productAuthVo.getExpireTime() <= now){ //表示已到期
                        productAuthVo.setExpireStatus(1);
                    }else{ //正常
                        productAuthVo.setExpireStatus(0);
                    }
                }else{
                    productAuthVo.setProductAuthStatus(0); //未授权
                }

                //产品按月购买
                ProductPrice productPrice_month = productPriceMapper.selectByProductCodeAndAuthType(product.getCode(), DeviceAuthTypeEnum.DAT_MONTH.getId());
                if(productPrice_month != null){
                    productAuthVo.setMonthPrice(productPrice_month.getPrice());
                }

                //产品按年购买价格
                ProductPrice productPrice_year = productPriceMapper.selectByProductCodeAndAuthType(product.getCode(), DeviceAuthTypeEnum.DAT_YEAR.getId());
                if(productPrice_year != null){
                    productAuthVo.setYearPrice(productPrice_year.getPrice());
                }

                //判断该产品是否启用，默认为未启用
                if(merBaseConfig != null){
                    JSONArray valArray = JSONObject.parseArray(Tools.getStr(merBaseConfig.getVal()));
                    if(valArray != null && valArray.size() > 0){
                        //是否包含该设备KEY，包含了则设置为1，不包含为0
                        if(valArray.contains(product.getCode())){
                            productAuthVo.setStatus(1); //启用
                        }else{
                            productAuthVo.setStatus(0); //禁用
                        }
                    }else{
                        productAuthVo.setStatus(0); //禁用
                    }
                }else{
                    productAuthVo.setStatus(0);     //禁用
                }
                productAuthVoList.add(productAuthVo);
            }
        }


        //查询当前有效的产品
        DeviceProductQuery deviceProductQuery = new DeviceProductQuery();
        deviceProductQuery.setStatus(1); //1-有效；0-禁用
        deviceProductQuery.setType(0);   //基本包
        ArrayList<DeviceProduct> deviceProductList =  deviceProductMapper.findByList(deviceProductQuery);
        //循环遍历产品功能，如果该运营商启用了该产品功能，就设置status=1,否则status=0
        if(deviceProductList != null && deviceProductList.size() > 0){
            //查询当前运营商的设备类型配置
            MerBaseConfig merBaseConfig = merBaseConfigMapper.selectByMerId(merId, MerConfigKeyEnum.PRODUCT_SWITCH.getValue());
            for (DeviceProduct deviceProduct : deviceProductList){
                ProductAuthVo productAuthVo = new ProductAuthVo();
                //对象互相赋值属性
                BeanUtils.copyProperties(deviceProduct, productAuthVo);
                //设备产品
                productAuthVo.setProductType(1);

                //默认未授权
                productAuthVo.setProductAuthStatus(0); //未授权

                //判断该产品是否启用，默认为未启用
                if(merBaseConfig != null){
                    JSONArray valArray = JSONObject.parseArray(Tools.getStr(merBaseConfig.getVal()));
                    if(valArray != null && valArray.size() > 0){
                        //是否包含该设备KEY，包含了则设置为1，不包含为0
                        if(valArray.contains(deviceProduct.getCode())){
                            productAuthVo.setStatus(1); //启用
                        }else{
                            productAuthVo.setStatus(0); //禁用
                        }
                    }else{
                        productAuthVo.setStatus(0); //禁用
                    }
                }else{
                    productAuthVo.setStatus(0);     //禁用
                }

                //个人微信
                DeviceWechatInfoQuery deviceWechatInfoQuery = new DeviceWechatInfoQuery();
                deviceWechatInfoQuery.setMerId(merId);
                deviceWechatInfoQuery.setProductCode(deviceProduct.getCode());
                //授权总数
                Integer deviceWechantInfoCount = deviceWechatInfoMapper.findByCount(deviceWechatInfoQuery);
                deviceWechatInfoQuery.setExpireType(2); //即将到期
                Integer deviceWechantInfoCount_expiring = deviceWechatInfoMapper.findByCount(deviceWechatInfoQuery);
                deviceWechatInfoQuery.setExpireType(0); //已到期
                Integer deviceWechantInfoCount_expired = deviceWechatInfoMapper.findByCount(deviceWechatInfoQuery);

                //企业微信
                DeviceWxworkInfoQuery deviceWxworkInfoQuery = new DeviceWxworkInfoQuery();
                deviceWxworkInfoQuery.setMerId(merId);
                deviceWxworkInfoQuery.setProductCode(deviceProduct.getCode());
                //授权总数
                Integer deviceWxworkInfoCount = deviceWxworkInfoMapper.findByCount(deviceWxworkInfoQuery);
                deviceWxworkInfoQuery.setExpireType(2); //即将到期
                Integer deviceWxworkInfoCount_expiring = deviceWxworkInfoMapper.findByCount(deviceWxworkInfoQuery);
                deviceWxworkInfoQuery.setExpireType(0); //已到期
                Integer deviceWxworkInfoCoun_expired = deviceWxworkInfoMapper.findByCount(deviceWxworkInfoQuery);
                //公众号
                WxpubInfoListQuery wxpubInfoListQuery = new WxpubInfoListQuery();
                wxpubInfoListQuery.setMerId(merId);
                wxpubInfoListQuery.setProductCode(deviceProduct.getCode());
                //授权总数
                Integer wxpubInfoCount = wxpubInfoMapper.findByCount(wxpubInfoListQuery);
                wxpubInfoListQuery.setExpireType(2); //即将到期
                Integer wxpubInfoCount_expiring = wxpubInfoMapper.findByCount(wxpubInfoListQuery);
                wxpubInfoListQuery.setExpireType(0); //已到期
                Integer wxpubInfoCount_expired = wxpubInfoMapper.findByCount(wxpubInfoListQuery);

                //总共即将到期=个人微信+企业微信+公众号
                productAuthVo.setAuthCountExpiring(Tools.getInteger(deviceWechantInfoCount_expiring) + Tools.getInteger(deviceWxworkInfoCount_expiring) + Tools.getInteger(wxpubInfoCount_expiring));
                //总共已经到期=个人微信+企业微信
                productAuthVo.setAuthCountExpired(Tools.getInteger(deviceWechantInfoCount_expired) + Tools.getInteger(deviceWxworkInfoCoun_expired) + Tools.getInteger(wxpubInfoCount_expired));

                //总共授权机器人数
                productAuthVo.setAuthCountTotal(Tools.getInteger(deviceWechantInfoCount) + Tools.getInteger(deviceWxworkInfoCount) + Tools.getInteger(wxpubInfoCount));

                productAuthVoList.add(productAuthVo);
            }
        }
        return productAuthVoList;
    }

    /**
     * 产品购买
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param productBuyAuthDto
     * @return null
     */
    @Transactional
    public BuyProductAuthVo buyProductAuth(ProductBuyAuthDto productBuyAuthDto){
        //返回对象
        BuyProductAuthVo buyProductAuthVo = new BuyProductAuthVo();
        //业务号
        String trandeno = Tools.getCurrentTimeByFormat("yyyyMMdd") + IdWorker.getIdStr();
        //当前时间
        Integer now = DateUtil.getNowTime();

        if(StringUtils.isBlank(productBuyAuthDto.getProductCode())){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入产品编码");
        }

        Product product = productMapper.selectByCode(productBuyAuthDto.getProductCode());
        if(product == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "产品不存在");
        }

        if(productBuyAuthDto.getPayType() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入支付类型");
        }

        if(productBuyAuthDto.getAuthType() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入授权类型");
        }

        if(productBuyAuthDto.getQuantity() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入购买时长");
        }

        //单个的金额和月数
        Double amount = 0.00D;
        Double price = 0.00D;
        Integer quantity = productBuyAuthDto.getQuantity();
        if(productBuyAuthDto.getAuthType().intValue() == DeviceAuthTypeEnum.DAT_MONTH.getId().intValue()){//按月购买
            //产品按月购买
            ProductPrice productPrice_month = productPriceMapper.selectByProductCodeAndAuthType(productBuyAuthDto.getProductCode(), DeviceAuthTypeEnum.DAT_MONTH.getId());
            if(productPrice_month == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请先设置产品按月购买价格");
            }
            //总金额=按月单价乘以月份
            amount = Math.mul(Tools.getDouble(productPrice_month.getPrice()), quantity);
            price = Tools.getDouble(productPrice_month.getPrice());
        }else if(productBuyAuthDto.getAuthType().intValue() == DeviceAuthTypeEnum.DAT_YEAR.getId().intValue()){ //按年购买
            //产品按年购买价格
            ProductPrice productPrice_year = productPriceMapper.selectByProductCodeAndAuthType(productBuyAuthDto.getProductCode(), DeviceAuthTypeEnum.DAT_YEAR.getId());
            if(productPrice_year == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请先设置产品按年购买价格");
            }
            //总金额=按年单价乘以月份
            amount = Math.mul(Tools.getDouble(productPrice_year.getPrice()), quantity);
            price = Tools.getDouble(productPrice_year.getPrice());
            //按年购买，按12个月记录
            quantity = quantity * 12;
        }

        //判断支付类型
        if(productBuyAuthDto.getPayType().intValue() == PaymentTypeEnum.PAY_ALIPAY.getId().intValue()) {//支付宝支付

            //添加支付宝账单
            AlipayDetail alipayDetail = new AlipayDetail();
            alipayDetail.setId(IdWorker.getId());
            alipayDetail.setMerId(productBuyAuthDto.getMerId());
            alipayDetail.setTradeno(trandeno);
            alipayDetail.setType(AlipayTypeEnum.PRODUCT_AUTH.getId()); //产品授权
            //业务信息
            ProductAuthBusinessInfo productAuthBusinessInfo = new ProductAuthBusinessInfo();
            productAuthBusinessInfo.setProductCode(productBuyAuthDto.getProductCode());
            productAuthBusinessInfo.setAuthType(productBuyAuthDto.getAuthType());
            productAuthBusinessInfo.setQuantity(quantity);
            productAuthBusinessInfo.setAmount(amount);
            productAuthBusinessInfo.setPrice(price);
            alipayDetail.setBusinessInfo(Tools.getStrEmpty(JSONObject.toJSONString(productAuthBusinessInfo)));

            alipayDetail.setAmount(amount);
            alipayDetail.setStatus(AlipayStatusEnum.WAIT_BUYER_PAY.getId()); //等待付款
            alipayDetail.setCreateTime(now);
            alipayDetail.setUpdateTime(now);
            alipayDetail.setSubtype(productBuyAuthDto.getProductCode());//子交易类型(产品key)

            //请求支付宝申请订单
            AlipayDetailCreateDto alipayDetailCreateDto = new AlipayDetailCreateDto();
            alipayDetailCreateDto.setOutTradeNo(alipayDetail.getTradeno());
            alipayDetailCreateDto.setTotalAmount(alipayDetail.getAmount());
            alipayDetailCreateDto.setSubject(AlipayTypeEnum.PRODUCT_AUTH.getDesc());
            String alipayUrl = alipayDetailService.createAlipayDetail(alipayDetailCreateDto);
            if(StringUtils.isNotBlank(alipayUrl)){
                //将支付页面信息保存到数据库
                alipayDetail.setAlipayUrl(alipayUrl);
                //插入支付宝账单
                alipayDetailMapper.insertSelective(alipayDetail);

                //返回支付页面
                buyProductAuthVo.setAlipayUrl(uzaiConsoleSysConfig.getAlipayPaypageUrl()+"?id=" + alipayDetail.getId());
            }else{
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "调用支付宝失败");
            }
        }else if(productBuyAuthDto.getPayType().intValue() == PaymentTypeEnum.PAY_BALANCE.getId().intValue()){ //余额支付
            //处理余额支付信息
            //查询账号信息
            Merchant merchant = merchantMapper.selectById(productBuyAuthDto.getMerId());
            //判断余额大小
            Double balance = merchant.getBalance();
            if(balance.doubleValue() < amount){ //不够支付
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "账户余额不足");
            }

            //修改账户余额
            merchant.setBalance(balance-amount);
            merchant.setUpdateTime(now);
            merchantMapper.updateBalance(merchant);

            //添加账户明细
            MerAccDetail merAccDetail = new MerAccDetail();
            merAccDetail.setId(IdWorker.getId());
            merAccDetail.setMerId(merchant.getId());
            merAccDetail.setOperateType(2);//支出
            merAccDetail.setMoney(merchant.getBalance());
            merAccDetail.setCgMoney(amount);
            merAccDetail.setSourceType(MerAccDetailSourceTypeEnum.PRODUCT_AUTH.getId());//产品授权
            merAccDetail.setSubtype(productBuyAuthDto.getProductCode());//子交易类型(产品key);
            merAccDetail.setTradeno(trandeno);
            merAccDetail.setCreateTime(now);
            merAccDetail.setUpdateTime(now);
            merAccDetailMapper.insert(merAccDetail);

            Integer beginTime = now;  //授权开始时间
            Integer expireTime = now; //授权到期时间
            //添加产品授权表-如果没有则新增，有则修改
            ProductAuth productAuth = productAuthMapper.selectByMerIdAndProductCode(productBuyAuthDto.getMerId(), productBuyAuthDto.getProductCode());
            if(productAuth != null){//修改
                productAuth.setAuthType(productBuyAuthDto.getAuthType());
                //判断旧到期时间是否已经过期
                Integer old_expireTime = Tools.getInteger(productAuth.getExpireTime());
                if(old_expireTime <= now){//已经到期，则从今天开始算
                    beginTime = now;
                    expireTime = beginTime + quantity * 30 * 24 * 3600;
                }else{
                    beginTime = old_expireTime;
                    expireTime = beginTime + quantity * 30 * 24 * 3600;
                }
                productAuth.setExpireTime(expireTime);
                productAuth.setUpdateTime(now);
                productAuthMapper.updateById(productAuth);
            }else{
                productAuth = new ProductAuth();
                productAuth.setId(IdWorker.getId());
                productAuth.setMerId(productBuyAuthDto.getMerId());
                productAuth.setProductCode(productBuyAuthDto.getProductCode());
                productAuth.setAuthType(productBuyAuthDto.getAuthType());
                beginTime = now;
                expireTime = beginTime + quantity * 30 * 24 * 3600;
                productAuth.setExpireTime(expireTime);
                productAuth.setCreateTime(now);
                productAuth.setUpdateTime(now);
                productAuthMapper.insert(productAuth);
            }

            //添加产品授权明细表
            ProductAuthDetail productAuthDetail = new ProductAuthDetail();
            productAuthDetail.setId(IdWorker.getId());
            productAuthDetail.setMerId(productBuyAuthDto.getMerId());
            productAuthDetail.setProductCode(productBuyAuthDto.getProductCode());
            productAuthDetail.setAuthType(productBuyAuthDto.getAuthType());
            productAuthDetail.setQuantity(quantity); //试用为0
            productAuthDetail.setBeginTime(beginTime);
            productAuthDetail.setExpireTime(expireTime);
            productAuthDetail.setPayTime(now);
            productAuthDetail.setPayType(productBuyAuthDto.getPayType());
            productAuthDetail.setTradeno(trandeno);
            productAuthDetail.setAmount(amount);
            productAuthDetail.setRemark("余额支付");
            productAuthDetail.setCreateTime(now);
            productAuthDetail.setUpdateTime(now);
            productAuthDetailMapper.insert(productAuthDetail);
        }

        return buyProductAuthVo;
    }

    /**
     * 运营商产品功能模块启用禁用
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param merchantSetProductDto
     * @return null
     */
    @Transactional
    public Boolean setProduct(MerchantSetProductDto merchantSetProductDto){

        //设置数据库的数据
        Integer currentTime = DateUtil.getNowTime();

        Long merId = merchantSetProductDto.getMerId();

        //查询当前产品功能模块配置
        MerBaseConfig merBaseConfig_old = merBaseConfigMapper.selectByMerId(merId, MerConfigKeyEnum.PRODUCT_SWITCH.getValue());

        JSONArray valArray = null;
        if(merBaseConfig_old != null){ //如果存在，则修改
            String val = merBaseConfig_old.getVal();
            if(StringUtils.isNotBlank(val)){
                valArray = JSONObject.parseArray(val);
                //是否包含该功能模块KEY，包含了则设置为1，不包含为0
                if(merchantSetProductDto.getStatus() == 0){ //禁用
                    if(valArray.contains(merchantSetProductDto.getKey())){
                        valArray.remove(merchantSetProductDto.getKey());
                    }
                }else{ //启动
                    if(!valArray.contains(merchantSetProductDto.getKey())){
                        valArray.add(merchantSetProductDto.getKey());
                    }
                }
                //修改功能模块开关配置
                merBaseConfig_old.setVal(Tools.getStrEmpty(JSONObject.toJSONString(valArray)));
                merBaseConfig_old.setUpdateTime(currentTime);
                merBaseConfigMapper.update(merBaseConfig_old);
            }
        }else{ //如果没配置，新增配置
            MerBaseConfig merBaseConfig_new = new MerBaseConfig();
            merBaseConfig_new.setId(IdWorker.getId());
            merBaseConfig_new.setMerId(merId);
            merBaseConfig_new.setType(MerConfigTypeEnum.PRODUCTS.getValue());
            merBaseConfig_new.setKey(MerConfigKeyEnum.PRODUCT_SWITCH.getValue());
            valArray = new JSONArray();
            valArray.add(merchantSetProductDto.getKey());
            merBaseConfig_new.setVal(Tools.getStrEmpty(JSONObject.toJSONString(valArray)));
            merBaseConfig_new.setCreateTime(currentTime);
            merBaseConfig_new.setUpdateTime(currentTime);
            merBaseConfigMapper.insert(merBaseConfig_new);
        }

        //更新redis
        redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.PRODUCT_SWITCH.getKey(), merchantSetProductDto.getMerId()), Tools.getStrEmpty(JSONObject.toJSONString(valArray)));






        return true;
    }
}
